#include <stdlib.h>

#include "lib.h"
#include "vpsql.h"
#include "vpsaved.h"
#include "vpopts.h"
#include "odbc.h"
#include "missinggamenums.h"
#include "opts.h"
#include "vphand.h"
#include "vpgame.h"
#include "log.h"
#include "stdncerr.h"

VPokerSQL::VPokerSQL( VPConnection *pConn, ProgressiveTrackSQL *pTracker, Info *pInfo)
{
    m_pConn    = pConn;
    m_pTracker = pTracker;
    m_pInfo    = pInfo;


#ifdef USE_MISSINGGAMENUMS
    //missing game nums deleted in TrackSQL::~TrackSQL
    missinggamenums = new MissingGameNums(this, "pub_getTableIdentityBlackjack");
#endif
}



int32
VPokerSQL::trackNewGame(int32 bet, VPHand* dealt, VPokerSavedGame* saved,
    int32 *balance)
{    
    int32 result = VPGameBase::NG_FAILED;
    int32 comp;

    if (m_pTracker && m_pInfo)
    {
		if(m_pConn->shouldSaveGameData())
		{
			m_pTracker->lock();
			result = createGame(
				ServerOpts::casinoId,
				m_pInfo->pid,
				m_pInfo->gid,
				m_pInfo->machineID,
				m_pInfo->forMoney,
				m_pInfo->sessionId,
				m_pInfo->forMoney ? m_pConn->getCompFactor() : 0,
				bet,
				dealt->getCount(),
				dealt->getCards(),
				m_pConn->getCreditValue(),
				saved,
				balance,
				&comp);
			m_pTracker->unlock();
		}
		else
		{
			//if we are not saving fun play data, we must deduct the bet amount
			//from the account when the game begins
			m_pTracker->adjustBalance(ServerOpts::casinoId,m_pInfo->pid,false,-bet,balance,&comp);
			result = ProgressiveTrackSQL::NoError;
		}

        switch (result)
        {
            case ProgressiveTrackSQL::NoError:
                result = VPGameBase::NG_OK;
                break;

            case VPokerSQL::NotEnoughMoney:
                result = VPGameBase::NG_NOMONEY;
                break;

            default:
                result = VPGameBase::NG_FAILED;
                break;
        }
    }

    return result;
}

bool8
VPokerSQL::trackDraw(VPHand* drawn, int32 payout, int32 paytype,
    bool8 dblUpActive, int32* balance)
{    
    int32 result = ProgressiveTrackSQL::ExecFailed;
    int32 comp;

    if (m_pTracker && m_pInfo)
    {
		if(m_pConn->shouldSaveGameData())
		{
			m_pTracker->lock();
			result = draw(
				ServerOpts::casinoId,
				m_pInfo->pid,
				m_pInfo->gid,
				m_pInfo->machineID,
				m_pInfo->forMoney,
				m_pConn->getCreditValue(),
				drawn->getCount(),
				drawn->getCards(),
				payout,
				paytype,
				dblUpActive,
				balance,
				&comp);
			m_pTracker->unlock();
		}
		else
		{
			//if not saving funplay game data, if double up is active, do not update
			//the account balance yet, if it is not active then update it
			if(dblUpActive)
				m_pTracker->getBalance(ServerOpts::casinoId,m_pInfo->pid,false,balance,&comp);
			else
				m_pTracker->adjustBalance(ServerOpts::casinoId,m_pInfo->pid,false,payout,balance,&comp);

			result = ProgressiveTrackSQL::NoError;
		}
    }

    return (bool8)(result == ProgressiveTrackSQL::NoError);
}

bool8
VPokerSQL::trackDoubleUpDeny(int32 payout, int32* balance)
{
    int32 result = ProgressiveTrackSQL::ExecFailed;
    int32 comp;

    if (m_pTracker && m_pInfo)
    {
		if(m_pConn->shouldSaveGameData())
		{
			m_pTracker->lock();
			result = doubleUpDeny(
				ServerOpts::casinoId,
				m_pInfo->pid,
				m_pInfo->gid,
				m_pInfo->machineID,
				m_pInfo->forMoney,
				m_pConn->getCreditValue(),
				payout,
				balance,
				&comp);
			m_pTracker->unlock();
		}
		else
		{
			//if we are not saving funplay game data, we must update the
			//account balance with the amount won (double up was denied)
			m_pTracker->adjustBalance(ServerOpts::casinoId,m_pInfo->pid,false,payout,balance,&comp);
			result = ProgressiveTrackSQL::NoError;
		}
    }

    return (bool8)(result == ProgressiveTrackSQL::NoError);
}

bool8
VPokerSQL::trackDoubleUpDeal(int32 round, uint8 dealt, ShueSave* shueSave,
    int32* balance)
{
    int32 result = ProgressiveTrackSQL::ExecFailed;
    int32 comp;

    if (m_pTracker && m_pInfo)
    {
		if(m_pConn->shouldSaveGameData())
		{
			m_pTracker->lock();
			result = doubleUpDeal(
				ServerOpts::casinoId,
				m_pInfo->pid,
				m_pInfo->gid,
				m_pInfo->forMoney,
				round,
				dealt,
				shueSave,
				balance,
				&comp);
			m_pTracker->unlock();
		}
		else
		{
			m_pTracker->getBalance(ServerOpts::casinoId,m_pInfo->pid,false,balance,&comp);
			result = ProgressiveTrackSQL::NoError;
		}
    }

    return (bool8)(result == ProgressiveTrackSQL::NoError);
}

bool8
VPokerSQL::trackDoubleUpDraw(int32 round, uint8 drawn, int32 winResult,
    int32 payout, int32* balance)
{
    int32 result = ProgressiveTrackSQL::ExecFailed;
    int32 comp;

    if (m_pTracker && m_pInfo)
    {
		if(m_pConn->shouldSaveGameData())
		{
			m_pTracker->lock();
			result = doubleUpDraw(
				ServerOpts::casinoId,
				m_pInfo->pid,
				m_pInfo->gid,
				m_pInfo->machineID,
				m_pInfo->forMoney,
				m_pConn->getCreditValue(),
				round,
				drawn,
				winResult < 0 ? 'W' : winResult > 0 ? 'L' : 'T',
				payout,
				balance,
				&comp);
			m_pTracker->unlock();
		}
		else
		{
			m_pTracker->getBalance(ServerOpts::casinoId,m_pInfo->pid,false,balance,&comp);
			result = ProgressiveTrackSQL::NoError;
		}
    }

    return (bool8)(result == ProgressiveTrackSQL::NoError);
}

bool8
VPokerSQL::processSavedGame(VPGameBase **ppGame, int32* err)
{
    VPokerSavedGame sg;
    int32 result = ProgressiveTrackSQL::ExecFailed;
    bool8 exists;

    if (m_pTracker && m_pInfo)
    {
        m_pTracker->lock();

        result = hasSavedGame(m_pInfo->pid, m_pInfo->machineID, m_pConn->getCreditValue(),
                              m_pInfo->forMoney, m_pInfo->gid, &sg, &exists);

        if (result == ProgressiveTrackSQL::NoError && exists)
        {
            *ppGame = new VPGame(m_pConn, this, &sg);
            if ((*ppGame)!=NULL && (*ppGame)->initOk())
            {
                m_pTracker->unlock();
                return true;
            }

            m_pTracker->unlock();

            delete (*ppGame);
            (*ppGame) = NULL;

            *err = LOGINERR_CONTACTCUSTSERVICE;
            return false;
        }
        else
        {
            memset(m_pInfo->gid, 0xff, sizeof(VPokerGameID));

            if (ProgressiveTrackSQL::NoError == result)
            {
                m_pTracker->unlock();

                *err = 0;
                return false;            // all ok, no saved game
            }
        }

        m_pTracker->unlock();
    }
    *err = LOGINERR_CONTACTCUSTSERVICE;
    return false;
}



bool8
VPokerSQL::trackNewSubGame()
{
    if (m_pTracker && m_pInfo)
    {
		if(m_pConn->shouldSaveGameData())
		{
			m_pTracker->lock();
			int nSubGameLength = m_pConn->getSubGameLength();
			uint8* pucSubGameData = m_pConn->getSubGameData();
			for(int32 i=0;i<nSubGameLength;i++)
			{
				setSubGameData(m_pInfo->gid, (uint8)i, (uint8)pucSubGameData[i]);
			}
			m_pTracker->unlock();
		}
    }
    return true;
}

bool8
VPokerSQL::trackGetSubGame()
{
    if (m_pTracker && m_pInfo)
    {
        m_pTracker->lock();
        uint8* pucSubGameData = m_pConn->getSubGameData();
        int32* pnSubGameLength = m_pConn->getSubGameLengthByRef();
        for(int32 i=0;i<VPConnection::MAX_SUBGAME_DATA;i++)
        {
            if(!(getSubGameData(m_pInfo->gid, (uint8)i, pucSubGameData)))
            {
                *pnSubGameLength = i;
                break;
            }
        }
        m_pTracker->unlock();
    }
    return true;
}



int32
VPokerSQL::getOptions(VPokerOpts* opts, uint8 machId, int32 creditValue)
{
    ODBCConnection* conn;
    ODBCQuery* query;
    bool8 ok = false;

    localCurrency lc;

	ok = m_pTracker->getLocale(&lc) == ProgressiveTrackSQL::NoError;

    if (!ok)
    {
        return ok;
    }

    conn = m_pTracker->getConn();
    if (!conn)
        return ProgressiveTrackSQL::NoConnection;

    query = conn->query();
    if (query)
    {
        query->define("exec pub_VPokerGetOptions ");
        query->addParam(machId, ODBCQuery::BINARY);
		query->addParam(creditValue);
        query->addParam(lc.int_curr_symbol);

        if (query->exec())
        {
            opts->payFreq = VPokerOpts::LO;
            opts->dblUpEnabled = false;

            while (query->getRow())
            {
                ok =
                    query->getData(1, &opts->payFreq) &&
                    query->getData(2, &opts->dblUpEnabled);
            }
        }
		delete query;
    }

	//psharpless 10/20/06
	//Case: 11052  New Double Up Win Cap Logic

	//get the new global options data
	if(ok)
	{
        query = conn->query();
        if (query)
        {
			query->define("exec pub_VPokerGetOptionsGlobal ");

			if (query->exec())
			{
				while (query->getRow())
				{
					ok = query->getData(1, &opts->dlbUpCapAmount);
				}
			}
			delete query;
		}
	}

	// psharpless #15914  
    // Get the list of supported credit values, no longer hardcoded
    if(ok)
    {
        query = conn->query();
        if (query)
        {
            query->define("exec pub_VPokerGetCreditValues ");
			query->addParam(lc.int_curr_symbol);

            if (query->exec())
            {
                int nCount=0;

                // get the 5 (and ONLY 5) credit values.
                while (ok && nCount<5 && query->getRow())
                {
                    ok = query->getData(1, &opts->anCreditValues[nCount++]);                    
                }

                if(nCount!=5)
                {
                    ok=false;
                }
            }
            delete query;
        }
    }
    delete conn;

    if (ok &&
        opts->payFreq >= VPokerOpts::LO &&
        opts->payFreq <= VPokerOpts::CUSTOM)	// CSN-6225
        return ProgressiveTrackSQL::NoError;
    else
        return ProgressiveTrackSQL::ExecFailed;
}

int32
VPokerSQL::getPlayerLimits(const PID& pid, int32 gameId, uint8 machId,
    int32* compFactor)
{
    ODBCConnection* conn;
    ODBCQuery* query;
    bool8 ok = false;

    conn = m_pTracker->getConn();
    if (!conn)
        return ProgressiveTrackSQL::NoConnection;

    query = conn->query();
    if (query)
    {
        query->define("exec pub_lim_getPlayerLimits ");
        query->addParam(pid);
        query->addParam(gameId);
        query->addParam(machId, ODBCQuery::BINARY);

        if (query->exec())
        {
            while (query->getRow())
            {
                ok = query->getData(4, compFactor);
            }
        }
        delete query;
    }
    delete conn;

    return ok ? m_pTracker->isGameEnabled(gameId,machId) : ProgressiveTrackSQL::ExecFailed;
}

int32
VPokerSQL::createGame(
    int32 casinoId, const PID& pid, VPokerGameID gid, uint8 machineID,
    bool8 forMoney, SESSIONID sessionId, int32 compFactor,
    int32 bet, int32 numDealt, uint8* dealt,
    int32 creditValue, VPokerSavedGame* saved,
    int32 *balance, int32* comp)
{
    ODBCConnection* conn;
    ODBCQuery* query;
    bool8 ok = false;
    int32 result=0;

    conn = m_pTracker->getConn();
    if (!conn)
        return ProgressiveTrackSQL::NoConnection;

    query = conn->query();
    if (query)
    {
        query->define("exec pub_CreateGameVPoker ");
        query->addParam(casinoId);
        query->addParam(pid);
        query->addParam(machineID, ODBCQuery::BINARY);
        query->addParam((bool8)(forMoney != 0));
        query->addParam(sessionId, ODBCQuery::NOQUOTES);
        query->addParam(compFactor);
        //
        // new game info
        //
        query->addParam(bet, ODBCQuery::MONEY);
        query->addParam(dealt, numDealt, ODBCQuery::BINARY);
        // 
        // saved game info
        //
        query->addParam(creditValue);
        query->addParam((int32)saved->shue.seed);
        query->addParam(saved->shue.next);
        query->addParam((int32)saved->payFreq);
        query->addParam((bool8)(saved->dblUpEnabled != 0));

        if (query->exec())
        {
            while (query->getRow())
            {
                ok =
                    query->getData(1, &result) &&
                    query->getData(2, gid, VPOKER_GAMEID_SIZE) &&
                    query->getData(3, balance, ODBCQuery::MONEY) &&
                    query->getData(4, comp);
            }
        }
        delete query;
    }
    delete conn;

    if (ok && result == 0)
    {
#ifdef USE_MISSINGGAMENUMS
        int32 gamenum = atol(gid);
        if (missinggamenums)
            missinggamenums->setGameNum(gamenum);
#endif

        return ProgressiveTrackSQL::NoError;
    }
    else if (ok && result == -1)
        return NotEnoughMoney;
    else
        return ProgressiveTrackSQL::ExecFailed;
}

int32
VPokerSQL::draw(
    int32 casinoId, const PID& pid, VPokerGameID gid, uint8 machineID,
    bool8 forMoney, int32 creditValue,
    int32 numDrawn, uint8* drawn,
    int32 payout, int32 paytype,
    bool8 dblUpActive,
    int32* balance, int32* comp)
{
    ODBCConnection* conn;
    ODBCQuery* query;
    bool8 ok = false;
    int32 result=0;

    conn = m_pTracker->getConn();
    if (!conn)
        return ProgressiveTrackSQL::NoConnection;
    
    query = conn->query();
    if (query)
    {
        query->define("exec pub_VPokerDraw ");
        query->addParam(casinoId);
        query->addParam(pid);
        query->addParam(machineID, ODBCQuery::BINARY);
        query->addParam((bool8)(forMoney != 0));
        query->addParam(creditValue);
        query->addParam(gid, ODBCQuery::NOQUOTES);
        query->addParam(drawn, numDrawn, ODBCQuery::BINARY);
        query->addParam(payout, ODBCQuery::MONEY);
        query->addParam((uint8)(paytype & 0xffL), ODBCQuery::BINARY);
        query->addParam((bool8)(dblUpActive != 0));

        if (query->exec())
        {
            while (query->getRow())
            {
                ok =
                    query->getData(1, &result) &&
                    query->getData(2, balance, ODBCQuery::MONEY) &&
                    query->getData(3, comp);
            }
        }
        delete query;
    }
    delete conn;
	
	// bwardlow 4-Apr-2006 #9353
	// The balance returned by the pub_VPokerDraw procedure does not include any bonus balance
	// and therefore can cause the Flash client to generate the "Your balance is currently
	// too low to place a bet" message.  However, the pub_bank_GetAccountBalance procedure
	// handles this correctly, so let's just call it here to make sure that everyone is getting
	// a good balance value.
	int32 myBalance;
	int32 myComp;
	int32 myBonusBalance;
	int32 myPlaythroughBalance;

	if (m_pTracker->getBalance(casinoId, pid, (bool8)(forMoney != 0), &myBalance,
		&myComp, &myBonusBalance, &myPlaythroughBalance) == ProgressiveTrackSQL::NoError)
	{
		*balance = myBalance;
	}

    return ok && result == 0 ? ProgressiveTrackSQL::NoError : ProgressiveTrackSQL::ExecFailed;
}

int32
VPokerSQL::doubleUpDeny(
    int32 casinoId, const PID& pid, VPokerGameID gid, uint8 machineID,
    bool8 forMoney, int32 creditValue,
    int32 payout,
    int32* balance, int32* comp)
{
    ODBCConnection* conn;
    ODBCQuery* query;
    bool8 ok = false;
    int32 result=0;

    conn = m_pTracker->getConn();
    if (!conn)
        return ProgressiveTrackSQL::NoConnection;
    
    query = conn->query();
    if (query)
    {
        query->define("exec pub_VPokerDblUpDeny ");
        query->addParam(casinoId);
        query->addParam(pid);
        query->addParam(machineID, ODBCQuery::BINARY);
        query->addParam((bool8)(forMoney != 0));
        query->addParam(creditValue);
        query->addParam(gid, ODBCQuery::NOQUOTES);
        query->addParam(payout, ODBCQuery::MONEY);

        if (query->exec())
        {
            while (query->getRow())
            {
                ok =
                    query->getData(1, &result) &&
                    query->getData(2, balance, ODBCQuery::MONEY) &&
                    query->getData(3, comp);
            }
        }
        delete query;
    }
    delete conn;

    return ok && result == 0 ? ProgressiveTrackSQL::NoError : ProgressiveTrackSQL::ExecFailed;
}
int32 
VPokerSQL::setSubGameData(VPokerGameID gid, uint8 index, uint8 data)
{
    ODBCConnection* conn;
    ODBCQuery* query;
    bool8 ok = false;
    int32 result=0;

    conn = m_pTracker->getConn();
    if (!conn)
        return ProgressiveTrackSQL::NoConnection;
    
    query = conn->query();
    if (query)
    {
        query->define("exec pub_CreateVPokerSubGame ");
        query->addParam(gid);
        query->addParam(index);
        query->addParam(data);

        if (query->exec())
        {
            while (query->getRow())
            {
                ok =
                    query->getData(1, &result);
            }
        }
        delete query;
    }
    delete conn;

    return ok && result == 0 ? ProgressiveTrackSQL::NoError : ProgressiveTrackSQL::ExecFailed;
}

bool8 
VPokerSQL::getSubGameData(VPokerGameID gid, uint8 index, uint8* data)
{
    ODBCConnection* conn;
    ODBCQuery* query;
    bool8 ok = false;
    bool8 result = false;
    uint8 tinyint;
    bool8 isnull = true;

    conn = m_pTracker->getConn();
    if (!conn)
        return ProgressiveTrackSQL::NoConnection;
    
    query = conn->query();
    if (query)
    {
        query->define("exec pub_VPokerGetSubGame ");
        query->addParam(gid);
        query->addParam(index);
        
        if (query->exec())
        {
            if (query->getRow())
            {
                ok =
                    query->getData(1, &tinyint, &isnull);

                if (!isnull)
                {
                    data[index] = tinyint;
                    result = true;
                }
                else
                {
                    data[index] = 0;
                    result = false;
                }
            }
        }
        delete query;
    }
    delete conn;

    return result;
}



int32
VPokerSQL::doubleUpDeal(
    int32 casinoId, const PID& pid, VPokerGameID gid, bool8 forMoney,
    int32 round, uint8 dealt, ShueSave* shueSave,
    int32* balance, int32* comp)
{
    ODBCConnection* conn;
    ODBCQuery* query;
    bool8 ok = false;
    int32 result=0;

    conn = m_pTracker->getConn();
    if (!conn)
        return ProgressiveTrackSQL::NoConnection;
    
    query = conn->query();
    if (query)
    {
        query->define("exec pub_VPokerDblUpDeal ");
        query->addParam(casinoId);
        query->addParam(pid);
        query->addParam((bool8)(forMoney != 0));
        query->addParam(gid, ODBCQuery::NOQUOTES);
        query->addParam(round);
        query->addParam((int32)shueSave->seed);
        query->addParam(&dealt, 1, ODBCQuery::BINARY);

        if (query->exec())
        {
            while (query->getRow())
            {
                ok =
                    query->getData(1, &result) &&
                    query->getData(2, balance, ODBCQuery::MONEY) &&
                    query->getData(3, comp);
            }
        }
        delete query;
    }
    delete conn;

    return ok && result == 0 ? ProgressiveTrackSQL::NoError : ProgressiveTrackSQL::ExecFailed;
}

int32
VPokerSQL::doubleUpDraw(
    int32 casinoId, const PID& pid, VPokerGameID gid, uint8 machineID,
    bool8 forMoney, int32 creditValue,
    int32 round, uint8 drawn, uint8 winResult, int32 payout,
    int32* balance, int32* comp)
{
    ODBCConnection* conn;
    ODBCQuery* query;
    bool8 ok = false;
    int32 result=0;

    conn = m_pTracker->getConn();
    if (!conn)
        return ProgressiveTrackSQL::NoConnection;
    
    query = conn->query();
    if (query)
    {
        query->define("exec pub_VPokerDblUpDraw ");
        query->addParam(casinoId);
        query->addParam(pid);
        query->addParam(machineID, ODBCQuery::BINARY);
        query->addParam((bool8)(forMoney != 0));
        query->addParam(creditValue);
        query->addParam(gid, ODBCQuery::NOQUOTES);
        query->addParam(round);
        query->addParam(&drawn, 1, ODBCQuery::BINARY);
        query->addParam(&winResult, 1, ODBCQuery::BINARY);
        query->addParam(payout, ODBCQuery::MONEY);

        if (query->exec())
        {
            while (query->getRow())
            {
                ok =
                    query->getData(1, &result) &&
                    query->getData(2, balance, ODBCQuery::MONEY) &&
                    query->getData(3, comp);
            }
        }
        delete query;
    }
    delete conn;

    return ok && result == 0 ? ProgressiveTrackSQL::NoError : ProgressiveTrackSQL::ExecFailed;
}

int32
VPokerSQL::hasSavedGame(const PID& pid, uint8 machID, int32 creditValue,
    bool8 forMoney, VPokerGameID gid, VPokerSavedGame* dest, bool8* exists)
{
    ODBCConnection* conn;
    ODBCQuery* query;
    bool8 ok = false;

    *exists = false;

    conn = m_pTracker->getConn();
    if (!conn)
        return ProgressiveTrackSQL::NoConnection;
    
    query = conn->query();
    if (query)
    {
        query->define("exec pub_VPokerGetSavedGame ");
        query->addParam(pid);
        query->addParam(machID, ODBCQuery::BINARY);
        query->addParam(creditValue);
        query->addParam((bool8)(forMoney != 0));

        if (query->exec())
        {
            int32 hasSaved = 0;
            int16 smallint=0;
            int32 numcards=0, numcards2=0;
            int8 payfreq=0, tinyint=0;
            uint8 paytype=0;
            char lastDblUpOutcome[2];

            while (query->getRow())
            {
                ok = query->getData(1, &hasSaved);

                if (!ok)
                    continue;

                switch (hasSaved)
                {
                    case 0:    // no saved game of any kind
                        break;

                    case 999:   
                    {
                        // kharmon.  10-06-06.  #15513.  There was a saved game, but it's incomplete for some reason.
                        // The stored procedure deleted the saved game record, so now the player can continue.  But, 
                        // first make in entry in the log noting this error.
                        char   gid[VPOKER_GAMEID_SIZE];
                        memset(gid, 0, sizeof(gid));
                        query->getData(2, gid, VPOKER_GAMEID_SIZE);

                        Log::msgError("A saved game could not be restored for gameid %s.", gid);
                        break;
                    }
                    case 1: // vpoker saved game
                        ok =
                            query->getData(2, gid, VPOKER_GAMEID_SIZE) &&
                            query->getData(3, &dest->bet, ODBCQuery::MONEY) &&
                            query->getData(4, &dest->shue.seed) &&
                            query->getData(5, &smallint) &&
                            query->getData(6, dest->cards,
                                VPokerSavedGame::MAXCARDS, &numcards) &&
                            query->getData(7, &payfreq) &&
                            query->getData(8, &tinyint); 

                        if (ok)
                        {
                            ASSERT(numcards == VPokerSavedGame::MAXCARDS);
                            dest->shue.next = smallint;
                            dest->payFreq = payfreq;
                            dest->dblUpEnabled = tinyint;
                            dest->dblUpLastDealt[0] = 0;    // not used
                            dest->dblUpLastOutcome = 0;        // not used
                            dest->dblUpOrigPayType = 0;        // not used
                            dest->dblUpPayType = 0;            // not used
                            dest->dblUpPayout = 0;            // not used
                            dest->dblUpWins = 0;            // not used
                            dest->dblUpRound = 0;            // not used
                            dest->kind = VPokerSavedGame::VPOKER_PLAYING;

                            *exists = true;
                        }
                        break;

                    case 2:    // dblup saved game...dblup available, 1st time
                        ok =
                            query->getData(2, gid, VPOKER_GAMEID_SIZE) &&
                            query->getData(3, &dest->bet,
                                ODBCQuery::MONEY) &&
                            query->getData(4, &payfreq) &&
                            query->getData(5, dest->dblUpLastDealt,
                                VPokerSavedGame::MAXCARDS, &numcards) &&
                            query->getData(6, dest->cards,
                                VPokerSavedGame::MAXCARDS, &numcards2) &&
                            query->getData(7, &paytype) &&
                            query->getData(8, &dest->dblUpPayout,
                                ODBCQuery::MONEY);

                        if (ok)
                        {
                            ASSERT(numcards == VPokerSavedGame::MAXCARDS);
                            ASSERT(numcards2 == VPokerSavedGame::MAXCARDS);

                            dest->payFreq = payfreq;
                            dest->dblUpOrigPayType = paytype;
                            dest->dblUpPayType = paytype;
                            dest->dblUpWins = 0;
                            dest->dblUpRound = 0;
                            dest->dblUpEnabled = 1;
                            dest->shue.seed = 0;        // not used
                            dest->shue.next = 0;        // not used
                            dest->dblUpLastOutcome = 0;    // not used
                            dest->kind = VPokerSavedGame::DBLUP_AVAIL_1ST;

                            *exists = true;
                        }
                        break;

                    case 3:    // dblup saved game...dblup available, not 1st time
                        ok =
                            query->getData(2, gid, VPOKER_GAMEID_SIZE) &&
                            query->getData(3, &dest->bet,
                                ODBCQuery::MONEY) &&
                            query->getData(4, &payfreq) &&
                            query->getData(5, &dest->shue.seed) &&
                            query->getData(6, dest->cards,
                                VPokerSavedGame::MAXCARDS, &numcards) &&
                            query->getData(7, dest->cards + 1,
                                VPokerSavedGame::MAXCARDS - 1, &numcards2) &&
                            query->getData(8, &paytype) &&
                            query->getData(9, &dest->dblUpPayout,
                                ODBCQuery::MONEY) &&
                            query->getData(10, lastDblUpOutcome, 2) &&
                            query->getData(11, &dest->dblUpWins) &&
                            query->getData(12, &tinyint);

                        if (ok)
                        {
                            ASSERT(numcards == 1);
                            ASSERT(numcards2 == 1);

                            dest->dblUpLastOutcome = lastDblUpOutcome[0];
                            dest->payFreq = payfreq;
                            dest->dblUpOrigPayType = paytype;
                            dest->dblUpRound = tinyint;
                            dest->dblUpEnabled = 1;
                            dest->shue.next = 0;
                            dest->dblUpLastDealt[0] = 0;    // not used
                            dest->dblUpPayType = 0;            // not used
                            dest->kind = VPokerSavedGame::DBLUP_AVAIL_NOT1ST;

                            *exists = true;
                        }
                        break;

                    case 4:    // dblup saved game...dealt, 1st time
                    case 5:    // dblup saved game...dealt, not 1st time
                        ok =
                            query->getData(2, gid, VPOKER_GAMEID_SIZE) &&
                            query->getData(3, &dest->bet,
                                ODBCQuery::MONEY) &&
                            query->getData(4, &payfreq) &&
                            query->getData(5, &dest->shue.seed) &&
                            query->getData(6, dest->cards,
                                VPokerSavedGame::MAXCARDS, &numcards) &&
                            query->getData(7, &paytype) &&
                            query->getData(8, &dest->dblUpPayout,
                                ODBCQuery::MONEY) &&
                            query->getData(9, lastDblUpOutcome, 2) &&
                            query->getData(10, &dest->dblUpWins) &&
                            query->getData(11, &tinyint);

                        if (ok)
                        {
                            ASSERT(numcards == 1);

                            dest->dblUpLastOutcome = lastDblUpOutcome[0];
                            dest->payFreq = payfreq;
                            dest->dblUpOrigPayType = paytype;
                            dest->dblUpRound = tinyint;
                            dest->dblUpEnabled = 1;
                            dest->shue.next = 0;
                            dest->dblUpLastDealt[0] = 0;    // not used
                            dest->dblUpPayType = 0;            // not used
                            dest->kind = VPokerSavedGame::DBLUP_PLAYING;

                            *exists = true;
                        }
                        break;

                    default:
                        ok = false;
                        break;
                }
            }
        }
        delete query;
    }
    delete conn;

    return ok ? ProgressiveTrackSQL::NoError : ProgressiveTrackSQL::ExecFailed;
}

